'''
Author: devis.dong
Email: devis.dong@gmail.com
Date: 2022-10-22 13:44:47
LastEditTime: 2022-12-12 22:00:30
LastEditors: devis.dong
FilePath: \coding\20221210\fsocket.py
Description:
'''
import socket               # 导入 socket 模块
import struct
import json
from typing import Dict, Tuple
from mydefine import *
from myutils import *

def sendModel(s:socket.socket, head:Dict, body:bytes=bytes()):
    head = json.dumps(head, ensure_ascii=False).encode('utf-8')
    head = struct.pack('%ds' % len(head), head)
    head_len, body_len = len(head), len(body)
    data = head + body
    data_len = len(data)
    # 先发送4字节的头部数据长度和4字节的body数据长度
    try:
        s.send(struct.pack('II', head_len, body_len))
        logger.info('length to send %d', data_len)
        # 再发送真正的数据
        len_sended = 0
        while(len_sended < data_len):
            len_sended += s.send(data[len_sended:])
    except Exception as e:
        logger.error('socket send error:  %s', str(e))
        return
    logger.info('length sended %d', len_sended)

def recvModel(s:socket.socket) ->Tuple:
    try:
        # 前8字节分别表示head和body的长度
        head_len, body_len = struct.unpack('II', s.recv(8))
        logger.info('length to receive %d %d', head_len, body_len)
        # 继续接收真正的数据
        head = bytes()
        body = bytes()
        while len(head) < head_len:
            head += s.recv(head_len-len(head))
        while len(body) < body_len:
            body += s.recv(body_len-len(body))
        logger.info('length received %d %d', len(head), len(body))

        head = json.loads(struct.unpack('%ds' % len(head), head)[0].decode('utf-8'))
    except Exception as e:
        logger.error('socket send error:  %s', str(e))
        return None, None
    return head, body

def sendData(s:socket.socket, data:bytes):
    data_len = 0 if data is None else len(data)
    # 先发送4字节的头部数据长度和4字节的body数据长度
    s.send(struct.pack('I', data_len))
    logger.info('length to send %d', data_len)
    # 再发送真正的数据
    len_sended = 0
    while(len_sended < data_len):
        len_sended += s.send(data[len_sended:])
    logger.info('length sended %d', len_sended)

def recvData(s:socket.socket) -> bytes:
    # 再接收主体数据（连续内存数据，类型根据header中的type字段确定)
    # 前4字节表示后续的数据长度
    len_torecv = struct.unpack('I', s.recv(4))[0]
    logger.info('length to receive %d', len_torecv)
    # 继续接收真正的数据
    data:bytes = bytes()
    if len_torecv > 0:
        while len(data) < len_torecv:
            data += s.recv(len_torecv-len(data))
    logger.info('length received %d', len(data))

    return data
